package com.hilog.paymentservice.config;

import com.hilog.common.TraceConstants;
import com.hilog.common.TraceIdGenerator;
import org.slf4j.MDC;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

/**
 * Web配置类 - 实现链路追踪
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new TraceIdInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/health");
    }

    /**
     * 链路追踪拦截器
     */
    public static class TraceIdInterceptor implements HandlerInterceptor {

        private static final String TRACE_ID_HEADER = TraceConstants.TRACE_ID_HEADER;
        private static final String TRACE_ID_KEY = TraceConstants.TRACE_ID_KEY;

        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
            // 从请求头获取traceId
            String traceId = request.getHeader(TRACE_ID_HEADER);
            
            // 如果没有traceId，则生成一个新的
            if (traceId == null || traceId.trim().isEmpty()) {
                traceId = generateTraceId();
            }
            
            // 将traceId设置到MDC中
            MDC.put(TRACE_ID_KEY, traceId);
            
            // 将traceId添加到响应头中，方便后续服务使用
            response.addHeader(TRACE_ID_HEADER, traceId);
            
            return true;
        }

        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
            // 清理MDC中的traceId
            MDC.remove(TRACE_ID_KEY);
        }

        /**
         * 生成TraceId
         */
        private String generateTraceId() {
            return TraceIdGenerator.generateTraceId();
        }
    }
} 